package utwente.hmi.touchmol;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.util.LinkedList;
import java.util.ListIterator;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.Border;

import utwente.hmi.touchmol.elements.*;

import com.merl.diamondtouch.DtlibInputTframe;

/**
 * @author Jeroen Logtenberg
 */
public class QueueModeratorGUI extends TouchMolGUI {

	private static final long serialVersionUID = 1L;
	
	public static final int LOCATION_MODERATOR = 7003;
	public static final int LOCATION_TURNPANEL = 7004;
	public static final int LOCATION_QUEUEPANEL = 7005;
	
	private LinkedList<TurnPanel> panels;
	private ModeratorPanel moderatorPanel;
	private QueuePanel queuePanel;
	
	private final int moderator = USER_BLUE; //Specifies the user that has moderator status [0-4].
	private long[] lastTurnChange = new long[5];
	
	public QueueModeratorGUI(){
		super();
		
		lastTurnChange[0] = 0;
		lastTurnChange[1] = 0;
		lastTurnChange[2] = 0;
		lastTurnChange[3] = 0;
		lastTurnChange[4] = 0;
	}
	
	@Override
	/**
	 * The queuemoderator GUI has a larger vertical control bar than the normal moderator GUI,
	 * to incorporate the queue panel. It has buttons to allocate turns on the left side of 
	 * the application. The rest of the screen is made up of the molpanel and the bookmark panel
	 * on the right edge.
	 */
	void makeLayout() {
		
		SCALE = 5;
		
		int molpanelSize = (displayWidth / SCALE * (SCALE - 2)) + (displayWidth / SCALE) - 225;
		
		jmolView = new MolPanel(molpanelSize,displayHeight - 75);

		screens = new ScreenshotPanel((displayWidth / SCALE) - 2, displayHeight - 75);
		
		//panels.
		panels = new LinkedList<TurnPanel>();
		moderatorPanel = new ModeratorPanel(73, displayHeight - 75, moderator);
		
		queuePanel = new QueuePanel(75, displayHeight - 75, USER_BLUE);
		TurnPanel red = new TurnPanel(displayWidth / 2 - 2, 73, UserButton.getRedButton());
		TurnPanel green = new TurnPanel(displayWidth / 2 - 2, 73, UserButton.getGreenButton());
		TurnPanel yellow = new TurnPanel(73, displayHeight - 75 , UserButton.getYellowButton());
		panels.add(red); panels.add(green); panels.add(yellow);
		moderatorPanel.setVisible(true);
		getContentPane().setLayout(new BorderLayout(1,1));
		
		
		JPanel moderatorSection = new JPanel();
		moderatorSection.setLayout(new BorderLayout());
		moderatorSection.add(queuePanel, BorderLayout.WEST);
		moderatorSection.add(moderatorPanel, BorderLayout.EAST);
		getContentPane().add(moderatorSection, BorderLayout.WEST);
		
		JPanel bottompanel = new JPanel();
		bottompanel.setLayout(new BorderLayout());
		bottompanel.add(red, BorderLayout.WEST);
		bottompanel.add(green, BorderLayout.EAST);
		getContentPane().add(bottompanel, BorderLayout.SOUTH);
		
		getContentPane().add(yellow,BorderLayout.EAST);
		
		JPanel centerpanel = new JPanel();
		centerpanel.setLayout(new BorderLayout(1,1));
		centerpanel.add(jmolView, BorderLayout.CENTER);
		centerpanel.add(screens, BorderLayout.EAST);
		getContentPane().add(centerpanel);
		
		//getContentPane().add(moderatorPanel, BorderLayout.WEST);
		
		Border line = BorderFactory.createLineBorder(Color.white, 5);
		screens.setBorder(line);
		screens.setIgnoreRepaint(true);
		
	}

	@Override
	int determineLocation(int userID, DtlibInputTframe dtInputFrame) {
		
		debug("Input frame size: " + touchRect(dtInputFrame));
		Point center = calculateCenter(touchRect(dtInputFrame));
		
		if(jmolView.panelTouched(center))
			return LOCATION_MOLPANEL;
		else if(screens.panelTouched(center))
			return LOCATION_SCREENSHOTPANEL;
		else if(moderatorPanel.panelTouched(center)){
			handleModeratorInput(userID, center);
			return LOCATION_MODERATOR;
		} else if(queuePanel.panelTouched(center)){
			handleQueueInput(userID, center);
			return LOCATION_QUEUEPANEL;
		} else{
			ListIterator<TurnPanel> it = panels.listIterator();
			TurnPanel p;
			while(it.hasNext()){
				p = it.next();
				if(p.panelTouched(center)){
					handleRequest(userID, center, p);
					return LOCATION_TURNPANEL;
				}
			}
			return -1;
		}
	}
	
	/**
	 * Processes events in the turn panels of the users.
	 * @param userID
	 * @param center
	 * @param panel
	 */
	private void handleRequest(int userID, Point center, TurnPanel panel){
		long current = System.currentTimeMillis();
		long timeDiff = current - lastTurnChange[userID];
		long threshold = 500L; //Time threshold between turn actions in milliseconds.
		
		UserButton res = panel.buttonTouched(center);
		
		if(res != null && res.getUserID() == userID && timeDiff > threshold){
			if(currentTurn != userID && !panel.isQueued()){
				panel.requestTurn(res);
				requestTurn(UserButton.getButton(res.getUserID()));
				TouchMolGUI.debug("Requesting turn.");
			} else if(currentTurn != userID && panel.isQueued()){
				panel.releaseTurn(res);
				releaseTurn(UserButton.getButton(res.getUserID()));
				TouchMolGUI.debug("Leaving queue.");
			}
			lastTurnChange[userID] = current;
		} else{
			TouchMolGUI.debug("Wrong user touched panel.");
		}
		
	}
	
	/**
	  * Checks that the touching user is moderator, 
	  * then processes touch input in moderator panel.
	  * @param center The center of touch.
	  */
	 private void handleModeratorInput(int userID, Point center){
		 if(userID == moderator){
			 debug("Moderator recognized");
			 UserButton res = moderatorPanel.buttonTouched(center);
			 if(res != null){
				 debug("Releasing " + currentTurn + ", allocating turn to user " + res.getUserID());
				 releaseTurn(UserButton.getButton(currentTurn));
				 takeTurn(res);
			 } else{
				 debug("No user touched.");
			 }
		 } else{
			 debug("Unauthorized touch on moderator panel by user " + userID);
		 }
	 }
	 
	 /**
	  * Checks that the touching user is moderator, 
	  * then processes touch input in queue panel.
	  * @param center The center of touch.
	  */
	 private void handleQueueInput(int userID, Point center){
		 if(userID == moderator){
			 debug("Moderator recognized");
			 UserButton res = queuePanel.buttonTouched(center);
			 if(res != null){
				 debug("Dequeued user " + res);
				 releaseTurn(UserButton.getButton(currentTurn));
				 takeTurn(res);
			 } else{
				 debug("No user touched.");
			 }
		 } else{
			 debug("Unauthorized touch on queue panel by user " + userID);
		 }
	 }

	@Override
	public void releaseTurn(UserButton user) {
		moderatorPanel.releaseTurn(user);
		queuePanel.releaseTurn(user);
		ListIterator<TurnPanel> it = panels.listIterator();
		TurnPanel p;
		while(it.hasNext()){
			p = it.next();
			if(p.getUser() == user.getUserID())
				p.releaseTurn(user);
		}
		//currentTurn = -1;
		
	}

	@Override
	public void requestTurn(UserButton user) {
		queuePanel.requestTurn(user);
		
	}

	@Override
	public void takeTurn(UserButton user) {
		moderatorPanel.takeTurn(user);
		queuePanel.takeTurn(user);
		ListIterator<TurnPanel> it = panels.listIterator();
		TurnPanel p;
		//TouchMolGUI.debug("Checking for touch on " + location);
		while(it.hasNext()){
			p = it.next();
			if(p.getUser() == user.getUserID())
				p.takeTurn(user);
		}
		currentTurn = user.getUserID();
	}
	 
}
